package com.chrilwe.pigpig.filesystem.common.balance;

import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;

/**
  * 一致性hash算法，将视频放到各个服务器上
 * @author chrilwe
 * @date 2020-10-3
 */
public class ConsistenceHashProgramAlgorithm {
	
	private TreeMap<Integer, VideoServerNode> treeMap;
	
	//初始化服务器节点，构建hash环
	public ConsistenceHashProgramAlgorithm(List<VideoServerNode> nodes) {
		if(nodes != null && nodes.size() > 0) {
			treeMap = new TreeMap<Integer, VideoServerNode>();
			for (VideoServerNode videoServerNode : nodes) {
				String name = videoServerNode.getName();
				int hash = hash(name);
				treeMap.put(hash, videoServerNode);
			}
		}
	}
	
	public VideoServerNode getVideoServerNode(String videoUUID) {
		if(StringUtils.isNotEmpty(videoUUID)) {
			int hash = hash(videoUUID);
			SortedMap<Integer, VideoServerNode> tailMap = treeMap.tailMap(hash);
			if(tailMap == null || tailMap.size() <= 0) {
				return treeMap.firstEntry().getValue();
			}
			return tailMap.get(hash);
		}
		return null;
	}
	
	@SuppressWarnings("unused")
	private int hash(String key) {
		final int p = 16777619;
        int hash = (int) 2166136261L;
        for (int i = 0; i < key.length(); i++)
            hash = (hash ^ key.charAt(i)) * p;
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;
 
        // 如果算出来的值为负数则取其绝对值
        if (hash < 0)
            hash = Math.abs(hash);
        return hash;
	}
}
